package repodata

import (
	"compress/bzip2"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"os"
	"strings"
)

type ObjWithClose interface {
	Close() error
}

func closeObj(obj ObjWithClose) {
	if obj != nil {
		_ = obj.Close()
	}
}

type Context struct {
	From     string // link | dir
	Username string
	Password string
}

func DownloadFileFromLink(ctx Context, linkSqlite string, filePath string) error {
	resp, err := http.Get(linkSqlite)
	if err != nil {
		return fmt.Errorf("无法下载文件: %v", err)
	}
	defer closeObj(resp.Body)

	// 创建本地文件
	file, err := os.Create(filePath)
	defer closeObj(file)
	if err != nil {
		return fmt.Errorf("无法创建文件: %v", err)
	}

	// 将响应内容写入本地文件
	_, err = io.Copy(file, resp.Body)
	if err != nil {
		return fmt.Errorf("无法写入文件: %v", err)
	}

	fmt.Printf("文件已下载到 %s\n", filePath)
	return nil
}

// DecompressBZ2 解压.bz2文件到指定的目标文件
func DecompressBZ2(sourceFile, targetFile string) error {
	// 打开源文件
	src, err := os.Open(sourceFile)
	if err != nil {
		return fmt.Errorf("failed to open source file: %w", err)
	}
	defer closeObj(src)

	// 创建目标文件
	dst, err := os.Create(targetFile)
	if err != nil {
		return fmt.Errorf("failed to create target file: %w", err)
	}
	defer closeObj(dst)

	// 创建一个bzip2解压器
	reader := bzip2.NewReader(src)

	// 将解压后的内容写入目标文件
	_, err = io.Copy(dst, reader)
	if err != nil {
		return fmt.Errorf("failed to decompress file: %w", err)
	}
	return nil
}

const (
	CharsetDigits        = "0123456789"
	CharsetLetters       = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	CharsetSymbols       = "!@#$%^&*()-_=+"
	CharsetLettersDigits = CharsetLetters + CharsetDigits
	CharsetAll           = CharsetLettersDigits + CharsetSymbols
)

// GenerateRandomString 生成指定长度的随机字符串
func GenerateRandomString(length int, charset string) string {
	if charset == "" {
		charset = CharsetAll
	}
	// 创建一个字符串缓冲区
	var b strings.Builder
	// 生成随机字符串
	for i := 0; i < length; i++ {
		b.WriteByte(charset[rand.Intn(len(charset))])
	}
	return b.String()
}
